﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using OhioState.Tiling;
using UnityEngine;

namespace OhioState.Tiling
{
    class PerlinTileConstructionCPU
    {
        public PerlinTileConstructionCPU(PerlinNoiseTile tile)
        {
            noiseResolution = tile.TileData.width;
            this.tile = tile.TileData;
        }
        public float[,] GetConstructedNoiseTile(int width, int height)
        {
            float[,] constructedTile = new float[width, height];
            
            for(int i=0;i<width;i++)
            {
                //StringBuilder s = new StringBuilder();
                for(int j = 0;j<height;j++)
                {
                    float x = (float)i/(float)width;
                    float y  = (float)j/(float)height;
                   

                    float n = noise2d(x,y);
                    constructedTile[i, j] = n;
                    //s.Append(n.ToString()+" ");
                }
               // Debug.Log(s.ToString());
            }
            return constructedTile;
        }
        float fade(float t)
        {
            return t * t * t * (t * (t * 6 - 15) + 10);
        }

        int perm(int x, int y)
        {
            int u = (int)((float)x / (float)(noiseResolution - 1.0f+0.1f)*noiseResolution);
            int v = (int)((float)y / (float)(noiseResolution - 1.0f+0.1f)*noiseResolution);
           
            return (int)(tile.GetPixel(u,v).r *256.0f);
        }

        float grad(int t, float x, float y)
        {
            int h = t % 16;
            float u = h < 8.0f ? x : y;
            float v = h < 4.0f ? y : x;
            float a = h % 2 == 0 ? u : -u; h /= 2;
            float b = h % 2 == 0 ? v : -v;
            return a + b;
        }
        float lerp(float t, float a, float b)
        {
            return a + t * (b - a);
        }
        float noise2d(float a, float b)
        {
            float x = a*(noiseResolution - 1.0f) ;
            float y = b*(noiseResolution - 1.0f) ;

            int X = (int)(x);
            int Y = (int)(y);

            x = x - X;
            y = y - Y;

            float u = fade(x);
            float v = fade(y);

            int AA = perm(X, Y);
            int AB = perm(X + 1, Y);
            int BA = perm(X, Y + 1);
            int BB = perm(X + 1, Y + 1);

            return lerp(v, lerp(u, grad(AA, x, y),
                                   grad(AB, x - 1.0f, y)),
                           lerp(u, grad(BA, x, y - 1.0f),
                                   grad(BB, x - 1.0f, y - 1.0f)));
            
             
            //return AA;
        }
        private int noiseResolution;
        private Texture2D tile;
    }
}
